;;======================================================================================================================
;;///// mpu.asm //////////////////////////////////////////////////////////////////////////////////////////// GPLv2 /////
;;======================================================================================================================
;; (c) 2011 Ostin project <http://ostin.googlecode.com/>
;; (c) 2004-2009 KolibriOS team <http://kolibrios.org/>
;;======================================================================================================================
;; This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
;; License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later
;; version.
;;
;; This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License along with this program. If not, see
;; <http://www.gnu.org/licenses/>.
;;======================================================================================================================

uglobal
  ; device addresses
  mididp rd 1
  midisp rd 1
endg

;-----------------------------------------------------------------------------------------------------------------------
kproc is_input ;////////////////////////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
        push    edx
        mov     dx, word[midisp]
        in      al, dx
        and     al, 0x80
        pop     edx
        ret
kendp

;-----------------------------------------------------------------------------------------------------------------------
kproc is_output ;///////////////////////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
        push    edx
        mov     dx, word[midisp]
        in      al, dx
        and     al, 0x40
        pop     edx
        ret
kendp

;-----------------------------------------------------------------------------------------------------------------------
kproc get_mpu_in ;//////////////////////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
        push    edx
        mov     dx, word[mididp]
        in      al, dx
        pop     edx
        ret
kendp

;-----------------------------------------------------------------------------------------------------------------------
kproc put_mpu_out ;/////////////////////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
        push    edx
        mov     dx, word[mididp]
        out     dx, al
        pop     edx
        ret
kendp

;-----------------------------------------------------------------------------------------------------------------------
kproc sysfn.midi_ctl ;//////////////////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
;? System function 20
;-----------------------------------------------------------------------------------------------------------------------
iglobal
  jump_table sysfn.midi_ctl, subfn, sysfn.not_implemented, \
    reset, \ ; 1
    output_byte ; 2
endg
;-----------------------------------------------------------------------------------------------------------------------
        dec     ebx
        cmp     ebx, .countof.subfn
        jae     sysfn.not_implemented

        cmp     [mididp], 0
        je      .error

        jmp     [.subfn + ebx * 4]

  .error:
        mov     [esp + 4 + regs_context32_t.eax], 1
        ret
kendp

;-----------------------------------------------------------------------------------------------------------------------
kproc sysfn.midi_ctl.reset ;////////////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
;? System function 20.1
;-----------------------------------------------------------------------------------------------------------------------
    @@: call    is_output
        test    al, al
        jnz     @b

        mov     dx, word[midisp]
        mov     al, 0xff
        out     dx, al

    @@: mov     dx, word[midisp]
        mov     al, 0xff
        out     dx, al
        call    is_input
        test    al, al
        jnz     @b
        call    get_mpu_in
        cmp     al, 0xfe
        jnz     @b

    @@: call    is_output
        test    al, al
        jnz     @b

        mov     dx, word[midisp]
        mov     al, 0x3f
        out     dx, al

        and     [esp + 4 + regs_context32_t.eax], 0
        ret
kendp

;-----------------------------------------------------------------------------------------------------------------------
kproc sysfn.midi_ctl.output_byte ;//////////////////////////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------------------------------------------------
;? System function 20.2
;-----------------------------------------------------------------------------------------------------------------------
    @@: call    get_mpu_in
        call    is_output
        test    al, al
        jnz     @b

        mov     al, cl
        call    put_mpu_out

        and     [esp + 4 + regs_context32_t.eax], 0
        ret
kendp
